/**
 * @file crossover.h
 * @brief Genetic functions for combining 2 modules into 1
 * @author Scott Moyers
 * @date 2009
 */

#ifndef MY_CROSSOVER_H
#define MY_CROSSOVER_H

#include "module.h"
#include "dSFMT.h"

/** Creates a type for function pointers to crossover functions */
typedef struct Module *(*CrossoverFunc) (dsfmt_t *dsfmt, struct Module const *p1, struct Module const *p2);

/** number of crossover functions, update as necessary */
#define CROSS_FUNCS (3)

/**
 * picks a random point in the gate list and makes a child
 * from the left gates of the first parent and the right
 * gates of the second parent
 * @param dsfmt the random number generator
 * @param p1 the first parent
 * @param p2 the second parent
 * @return new child from the input parents
 */
struct Module *one_point_crossover(dsfmt_t *dsfmt, struct Module const *p1, struct Module const *p2);

/**
 * picks two random points in the gate list and makes a child
 * from the left and right gates of the first parent and the
 * middle gates of the second parent
 * @param dsfmt the random number generator
 * @param p1 the first parent
 * @param p2 the second parent
 * @return new child from the input parents
 */
struct Module *two_point_crossover(dsfmt_t *dsfmt, struct Module const *p1, struct Module const *p2);

/**
 * merges the 2 parent circuits uniformly.
 * first gate from a, second gate from b etc.
 * @param dsfmt the random number generator
 * @param p1 the first parent
 * @param p2 the second parent
 * @return new child from the input parents
 */
struct Module *uniform_crossover(dsfmt_t *dsfmt, struct Module const *p1, struct Module const *p2);

/**
 * gets a function pointer to the function named "func"
 * @param func name of a crossover function
 * @retval a function pointer
 * @retval NULL if the function doesn't exist
 */
CrossoverFunc get_crossover_func(const char *func);

#endif
